#include							"UdpBroadcastSocket.h"

UdpBroadcastSocket::UdpBroadcastSocket(boost::asio::io_service & service) : _socket(service, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0)), ASocket(0), _broadcast_endpoint(boost::asio::ip::address_v4::broadcast(), 4243), _heartbeat_timer(service)
{
	_type = ASocket::BROADCASTUDP;
	_socket.set_option(boost::asio::socket_base::broadcast(true));
	_socket.set_option(boost::asio::ip::udp::socket::reuse_address(true));
}

UdpBroadcastSocket::~UdpBroadcastSocket()
{

}

void								UdpBroadcastSocket::start()
{
	std::cout << "[INFO] Started UDP BROADCAST server on port " << _socket.local_endpoint().port() << std::endl;
	_startRead();
}

void								UdpBroadcastSocket::close()
{
	_socket.close();
}

boost::asio::ip::udp::socket		&UdpBroadcastSocket::getSocket()
{
	return _socket;
}

void								UdpBroadcastSocket::_startRead()
{
	Packet							packet;
	ProtocolOperator				protocol = MAIN;
	ProtocolMain					op = BROADCAST;

    packet.init();
    packet.pushData(&protocol, sizeof(protocol));
    packet.pushData(&op, sizeof(op));
	_socket.async_send_to(boost::asio::buffer(packet.toUdpNetworkPacket(), packet.size()), _broadcast_endpoint,  boost::bind(&UdpBroadcastSocket::_handle_heartbeat, this,
    boost::asio::placeholders::error));
}

 void                               UdpBroadcastSocket::_handle_heartbeat(const boost::system::error_code& ec)
{
    if (!ec)
    {
      _heartbeat_timer.expires_from_now(boost::posix_time::seconds(5));
	  _heartbeat_timer.async_wait(boost::bind(&UdpBroadcastSocket::_startRead, this));
    }
    else
    {
      std::cout << "Error on Broadcast: " << ec.message() << "\n";
          close();
    }
}

 std::string						UdpBroadcastSocket::getIp() const
 {
	 return _socket.local_endpoint().address().to_string();
 }
